#include<bits/stdc++.h>
using namespace std;
namespace fastio
{
	constexpr int S1=1<<20;
	char buf1[S1],*l1,*r1;
	inline char getc()
	{
		return ((l1==r1&&(r1=(l1=buf1)+fread(buf1,1,S1,stdin)),l1!=r1)?*l1++:EOF);
	}
	template<typename T=int>inline T read()
	{
		T x=0,y=1;
		char c=getc();
		for(;c<'0'||c>'9';c=getc())
			if(c=='-')
				y=-1;
		for(;c>='0'&&c<='9';c=getc())
			x=c-'0'+x*10;
		return x*y;
	}
	constexpr int S2=1<<20;
	char buf2[S2],*l2=buf2;
	inline void putc(char c)
	{
		l2==buf2+S2&&(fwrite(buf2,1,S2,stdout),l2=buf2),*l2++=c;
	}
	int st[22];
	template<typename T>inline void write(T x,char end='\n')
	{
		if(x<0)
			putc('-'),x=-x;
		int tp=0;
		do
			st[++tp]=x%10;
		while(x/=10);
		while(tp)
			putc(st[tp--]+'0');
		if(end)
			putc(end);
	}
	struct end
	{
		~end()
		{
			fwrite(buf2,1,l2-buf2,stdout);
		}
	}ender;
}
using fastio::getc;
using fastio::read;
using fastio::putc;
using fastio::write;
constexpr int MN=100005;
struct frac
{
	long long u,d;
	frac(long long x=0)
	{
		u=x,d=1;
	}
	frac(long long a,long long b)
	{
		u=a,d=b;
	}
	friend bool operator<(frac a,frac b)
	{
		return a.u*b.d<b.u*a.d;
	}
	friend bool operator<=(frac a,frac b)
	{
		return a.u*b.d<=b.u*a.d;
	}
	friend bool operator==(frac a,frac b)
	{
		return a.u*b.d==b.u*a.d;
	}
	friend bool operator!=(frac a,frac b)
	{
		return a.u*b.d!=b.u*a.d;
	}
	friend frac operator+(frac a,frac b)
	{
		long long d;
		if(a.d%b.d==0)
			d=a.d;
		else if(b.d%a.d==0)
			d=b.d;
		else
			d=a.d*b.d;
		return frac(d/a.d*a.u+d/b.d*b.u,d);
	}
	friend frac operator*(frac a,frac b)
	{
		return {a.u*b.u,a.d*b.d};
	}
	friend frac operator/(frac a,frac b)
	{
		return {a.u*b.d,a.d*b.u};
	}
}p[MN];
struct range
{
	frac l,r;
	bool lf,rf;
}a[MN];
long long V;
int T,n,m,L;
inline void work()
{
	T=read(),m=read(),L=read(),V=read();
	n=0;
	while(T--)
	{
		long long p0=read(),v0=read(),a0=read();
		if(!a0)
			if(v0>V)
				a[++n]={p0,L,1,1};
			else
				continue;
		else if(a0<0)
			if(v0<=V)
				continue;
			else
			{
				frac t(v0-V,-a0),r=p0+v0*t+a0*t*t/2;
				if(r<=L)
					a[++n]={p0,r,1,0};
				else
					a[++n]={p0,L,1,1};
			}
		else
			if(v0>V)
				a[++n]={p0,L,1,1};
			else
			{
				frac t(V-v0,a0),l=p0+v0*t+a0*t*t/2;
				if(l<L)
					a[++n]={l,L,0,1};
			}
	}
	for(int i=1;i<=m;i++)
		p[i]=read();
	int ans1=0,ans2=0,la=0;
	sort(a+1,a+n+1,[](range a,range b){
		if(a.r!=b.r)
			return a.r<b.r;
		return a.lf<b.lf;
	});
	for(int i=1,j=0;i<=n;i++)
	{
		if(la&&(a[i].l<p[la]||(a[i].l==p[la]&&a[i].lf))&&(p[la]<a[i].r||(p[la]==a[i].r&&a[i].rf)))
		{
			ans1++;
			continue;
		}
		for(;j<m&&(p[j+1]<a[i].r||(p[j+1]==a[i].r&&a[i].rf));j++);
		if(j&&(a[i].l<p[j]||(a[i].l==p[j]&&a[i].lf)))
			ans1++,ans2++,la=j;
	}
	printf("%d %d\n",ans1,m-ans2);
}
int main()
{
	freopen("detect.in","r",stdin);
	freopen("detect.out","w",stdout);
	int T=read();
	while(T--)
		work();
	return 0;
}